﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace Clandestine.Entities
{
    public abstract class Entity
    {
        public const float SpriteLayerDifference = 0.0001f;

        public virtual bool Solid
        {
            get { return (Sprite != null); }
        }

        public abstract Sprite Sprite { get; }

        public virtual bool PreserveState
        {
            get { return false; }
        }

        public virtual void OnCollide(int playerXPos, int playerYPos) { }

        public virtual void OnUse(int playerXPos, int playerYPos) { }

        public virtual bool CanUse
        {
            get { return false; }
        }

        private int useRadius = 5;

        public int UseRadius
        {
            get { return useRadius; }
            set { useRadius = value; }
        }

        public virtual Point Position
        {
            get { return Sprite.Position; }
            set { Sprite.Position = value; }
        }

        public virtual void Dispose()
        {
            if (Sprite != null)
                Sprite.Dispose();
        }

        public virtual Size Size
        {
            get { return Sprite.UnscaledSize; }
            set { throw new NotSupportedException(); }
        }

        public virtual bool SupportsResizing
        {
            get { return false; }
        }

        private string uuid = "";
        private string name = "";

        public string UUID
        {
            get { return uuid; }
            set { uuid = value; }
        }

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        public virtual float Layer
        {
            get { return Sprite.Layer - SpriteLayerDifference; }
            set { Sprite.Layer = value + SpriteLayerDifference; }
        }

        //private Rectangle collisionOffset = new Rectangle(0, 0, 0, 0);
        private Point collisionTopLeftOffset = new Point();
        private Point collisionBottomRightOffset = new Point();

        public virtual int CollisionOffsetLeft
        {
            get { return collisionTopLeftOffset.X; }
            set { collisionTopLeftOffset.X = value; }
        }

        public virtual int CollisionOffsetRight
        {
            get { return collisionBottomRightOffset.X; }
            set { collisionBottomRightOffset.X = value; }
        }

        public virtual int CollisionOffsetTop
        {
            get { return collisionTopLeftOffset.Y; }
            set { collisionTopLeftOffset.Y = value; }
        }

        public virtual int CollisionOffsetBottom
        {
            get { return collisionBottomRightOffset.Y; }
            set { collisionBottomRightOffset.Y = value; }
        }

        public virtual Rectangle CollisionRectangle
        {
            get
            {
                Rectangle rcoll = new Rectangle();
                rcoll.X = CollisionOffsetLeft + Position.X;
                rcoll.Y = CollisionOffsetTop + Position.Y;
                // Think about it -- if you set coLeft=5 and then you leave width the same,
                // the rectangle moves just 5px to the left and no actual radius change takes place..
                rcoll.Width = Size.Width - CollisionOffsetLeft - CollisionOffsetRight;
                rcoll.Height = Size.Height - CollisionOffsetTop - CollisionOffsetBottom;
                return rcoll;
            }
        }

        public virtual Rectangle UseRectangle
        {
            get
            {
                Rectangle ruse = new Rectangle();
                ruse.X = Position.X - UseRadius;
                ruse.Y = Position.Y - UseRadius;
                ruse.Width = Size.Width + UseRadius * 2;
                ruse.Height = Size.Height + UseRadius * 2;
                return ruse;
            }
        }

        public override string ToString()
        {
            return "'" + this.Name + "' (" + this.GetType().FullName + ") -" +
                (this.Sprite == null ? "no sprite" : "has sprite") + "- {"
                 + this.UUID + "}";
        }

        public virtual Dictionary<string, string> SaveState()
        {
            throw new NotImplementedException();
        }

        public virtual void LoadState(Dictionary<string, string> data)
        {
            throw new NotImplementedException();
        }

    }
}